﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "CmdStructureColumn.h"
#include "IStructureSlantedColumn.h"
#include "ActionDrawStructureVerticalColumn.h"
#include "ActionDrawStraightElementInput.h"
#include "ActionDrawStraightElementCreator.h"
#include "AddStructureDynamicPannelUtil.h"
#include "StructureCmdIds.h"
#include "GmUiStructureCommandRegister.h"
#include "StructureFamilyUiUtils.h"
#include "GbmpBuiltInCategoryUniIdentitiesNew.h"
#include "StructureDefaultFamilyNames.h"
#include "StructureCmdParamIds.h"
#include "StructureInstancePresetParameterUtils.h"
#include "StructureFamilyUtils.h"
#include "GbmpModelViewTypes.h"
#include "StructureInstanceCmdUtils.h"
#include "GbmpControlIds.h"

// 平台头文件
#include "IUiDocumentViewManager.h"
#include "IFamily.h"
#include "IDocument.h"
#include "IModelView.h"
#include "IMainWindow.h"
#include "IUiView.h"
#include "UiCommonDialog.h"
#include "IInstance.h"
#include "CommandParameters.h"
#include "GbmpPresetParameterUIUtils.h"
#include "IUserTransaction.h"
#include "Vector3dUtils.h"
#include "IGraphicsNodeGroup.h"
#include "IGraphicsLine.h"
#include "GcmpBuiltInCategoryUniIdentities.h"
#include "PropertyWidgetUtils.h"
#include "IPropertyPanelEventArgs.h"
#include "IInstanceType.h"
#include "ICommandManager.h"
#include "IGraphicsElementShape.h"
#include "GbmpGraphicsNodeUtils.h"
#include "IElementModelShape.h"
#include "IGraphicsStyleManager.h"
#include "GraphicsNodeUtils.h"
#include "UiDocumentViewUtils.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

#define ACTION_CHECK_ROTATE_AFTER_PLACE   L"gmCheckRotateAfterPlace"
#define ACTION_ANCHORPOINT                L"gmAnchorPoint"

using namespace gcmp;

//////////////////////////////////////////////////////////////////////////
CmdDrawStructureColumnBase::CmdDrawStructureColumnBase(const std::wstring &cmd):GbmpCommandBase(cmd)
{
}

bool CmdDrawStructureColumnBase::GetFamilyNameAndInstanceTypeFromCommandParams(const CommandParameters& cmdParams, std::wstring &familyName, std::wstring &instanceType)
{
    auto itorFamilyName = cmdParams.find(ID_CMD_PARAM_FAMILY_NAME);
    auto itorInstanceType = cmdParams.find(ID_CMD_PARAM_INSTANCE_TYPE);

    if (itorFamilyName != cmdParams.end() && itorInstanceType != cmdParams.end())
    {
        familyName = itorFamilyName->second.AsWString();
        instanceType=itorInstanceType->second.AsWString();
        return true;
    }

    return false;
}

bool CmdDrawStructureColumnBase::GetFamilyNameAndInstanceType(std::wstring &familyName, std::wstring& instanceType)
{
    IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    // 从预设参数读取
    bool bOk=StructureInstancePresetParameterUtils::GetPresetFamilyNameAndInstanceType(pDoc, this->GetCategory(), this->GetCategorySecondKey(), familyName, instanceType);
    if (bOk && !familyName.empty() && !instanceType.empty())
    {
        return true;
    }

    // 读取默认族、类型名称
    familyName = GetDefaultFamilyName();
    IFamily* pFamily = IFamily::GetFamilyByName(pDoc, familyName);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pFamily, L"pFamily为空",L"GDMPLab",L"2024-03-30");

    bOk = StructureFamilyUtils::GetFirstInstanceType(pFamily, instanceType);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(bOk&& !instanceType.empty(), L"GetFirstInstanceType失败",L"GDMPLab",L"2024-03-30");

    return true;
}

bool CmdDrawStructureColumnBase::CreateDefaultFamilyDocument()
{
    IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    std::wstring defaultRectColumnName = STRUCTURE_RECT_COLUMN_NAME;
    std::wstring defaultCircleColumnName = STRUCTURE_CIRCLE_COLUMN_NAME;

    StructureFamilyUiUtils::FamilyCreators defaultFamilyCreators
    {
        { defaultRectColumnName, BuiltInStructureFamilies::CreateBuildInRectangleColumnFamilyDocument },
        { defaultCircleColumnName, BuiltInStructureFamilies::CreateBuildInCircleColumnFamilyDocument }
    };

    StructureFamilyUiUtils::CreateFamilies(pDoc, defaultFamilyCreators);

    return true;
}

bool CmdDrawStructureColumnBase::OnExecuteCommand() const
{
    IModelView* pModelView = UiDocumentViewUtils::GetCurrentModelView();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");
    const std::wstring& viewType = pModelView->GetUserDataId();


    if (PlanViewType != viewType && View3DViewType != viewType) // TODO: 将来要支持在其它视图上绘制墙
    {
        IUiDocumentViewManager* pUiDocViewManager = IUiDocumentViewManager::Get();
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pUiDocViewManager, L"pUiDocViewManager为空",L"GDMPLab",L"2024-03-30");

        IUiView* pCurrentView = pUiDocViewManager->GetCurrentUiView();
        DBG_WARN_AND_RETURN_FALSE_UNLESS(nullptr != pCurrentView, L"pCurrentView为空",L"GDMPLab",L"2024-03-30");

        UiCommonDialog::ShowMessageBox(GBMP_TR(L"绘制柱"), GBMP_TR(L"此视图下暂时不支持绘制柱"), (int)UiCommonDialog::ButtonType::OK);
        ICommandManager::Get()->SendCommand(pCurrentView->GetDefaultActionCommand());
        return false;
    }
    return true;
}

//////////////////////////////////////////////////////////////////////////
CmdDrawStructureVerticalColumn::CmdDrawStructureVerticalColumn() : CmdDrawStructureColumnBase(ID_CMD_DRAW_STRUCTURE_VERTICAL_COLUMN)
{
}

bool CmdDrawStructureVerticalColumn::IsEnabled() const
{
    return true;
}

bool CmdDrawStructureVerticalColumn::IsVisible() const
{
    return true;
}

OwnerPtr<IAction> CmdDrawStructureVerticalColumn::ExecuteCommand(const CommandParameters& cmdParams)
{
    if (!OnExecuteCommand())
    {
        return nullptr;
    }

     //创建内建族
    bool bOk = CreateDefaultFamilyDocument();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(bOk, L"CreateDefaultFamilyDocument()失败",L"GDMPLab",L"2024-03-30");

    // 获取新创建实例的族Id、实例类型Id
    ElementId familyId;
    ElementId instanceTypeId;
    {
        std::wstring familyName;
        std::wstring instanceType;
        // 从命令参数读取
        bOk = GetFamilyNameAndInstanceTypeFromCommandParams(cmdParams, familyName, instanceType);

        // 从预设参数或默认读取
        if (!bOk)
        {
            bOk = GetFamilyNameAndInstanceType(familyName, instanceType);
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(bOk, L"GetFamilyNameAndInstanceType()失败",L"GDMPLab",L"2024-03-30");
        }

        IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

        const IFamily* pFamily = IFamily::GetFamilyByName(pDoc, familyName);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pFamily, L"pFamily为空",L"GDMPLab",L"2024-03-30");
        familyId = pFamily->GetElementId();

        const IInstanceType* pInstanceType = pFamily->GetInstanceTypeByName(instanceType);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pInstanceType, L"pInstanceType为空",L"GDMPLab",L"2024-03-30");
        instanceTypeId = pInstanceType->GetElementId();
    }

    OwnerPtr<ActionDrawStructureVerticalColumn> upAction = NEW_AS_OWNER_PTR(ActionDrawStructureVerticalColumn, GetCategory(), GetCategorySecondKey(), familyId, instanceTypeId);

    upAction->SetCommandId(GetCommandId());
    return TransferOwnership(upAction);
}

Int32 CmdDrawStructureVerticalColumn::GetCategorySecondKey() const
{
    return 0;
}

UniIdentity CmdDrawStructureVerticalColumn::GetCategory() const
{
    return BuiltInCategoryUniIdentities::BICU_STRUCTURE_COLUMN;
}

std::wstring CmdDrawStructureVerticalColumn::GetDefaultFamilyName() const
{
    return STRUCTURE_RECT_COLUMN_NAME;
}

REGISTER_GM_COMMAND(CmdDrawStructureVerticalColumn)

//////////////////////////////////////////////////////////////////////////

CmdDrawStructureSlantedColumn::CmdDrawStructureSlantedColumn() : CmdDrawStructureColumnBase(ID_CMD_DRAW_STRUCTURE_SLANTED_COLUMN)
{
}

bool CmdDrawStructureSlantedColumn::IsEnabled() const
{
    return true;
}

bool CmdDrawStructureSlantedColumn::IsVisible() const
{
    return true;
}

OwnerPtr<IAction> CmdDrawStructureSlantedColumn::ExecuteCommand(const gcmp::CommandParameters& cmdParams)
{
    if (!OnExecuteCommand())
    {
        return nullptr;
    }

    //创建内建族
    bool bOk = CreateDefaultFamilyDocument();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(bOk, L"CreateDefaultFamilyDocument()失败",L"GDMPLab",L"2024-03-30");

    // 获取新创建实例的族Id、实例类型Id
    ElementId familyId;
    ElementId instanceTypeId;
    {
        std::wstring familyName;
        std::wstring instanceType;
        // 从命令参数读取
        bOk = GetFamilyNameAndInstanceTypeFromCommandParams(cmdParams, familyName, instanceType);

        // 从预设参数或默认读取
        if (!bOk)
        {
            bOk = GetFamilyNameAndInstanceType(familyName, instanceType);
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(bOk, L"GetFamilyNameAndInstanceType()失败",L"GDMPLab",L"2024-03-30");
        }

        IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

        IFamily* pFamily = IFamily::GetFamilyByName(pDoc, familyName);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pFamily, L"pFamily为空",L"GDMPLab",L"2024-03-30");
        familyId = pFamily->GetElementId();

        const IInstanceType* pInstanceType = pFamily->GetInstanceTypeByName(instanceType);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pInstanceType, L"pInstanceType为空",L"GDMPLab",L"2024-03-30");
        instanceTypeId = pInstanceType->GetElementId();
    }

    SetFamilyIdAndInstanceTypeId(familyId, instanceTypeId);

    ActionDrawStraightElementInput actionInput;
    actionInput.CommandId = GetCommandId();
    actionInput.DrawLineMode = DrawLineMode::Separated;
    actionInput.LineFinishedCallback = ActionDrawStraightElementInput::CreateOnLineFinishedCallback(&CmdDrawStructureSlantedColumn::OnLineFinished, this);
    actionInput.LineUpdateCallback = ActionDrawStraightElementInput::CreateOnLineUpdateCallback(&CmdDrawStructureSlantedColumn::OnLineUpdate, this);
    actionInput.ActionInitCallback = ActionDrawStraightElementInput::CreateOnActionInitCallback(&CmdDrawStructureSlantedColumn::OnActionInit, this);
    actionInput.EnterGettingStartPointStateCallback = ActionDrawStraightElementInput::CreateOnEnterGettingStartPointStateCallback(
        &CmdDrawStructureSlantedColumn::OnEnterGettingStartPointState, this);
    actionInput.EnterGettingEndPointStateCallback = ActionDrawStraightElementInput::CreateOnEnterGettingEndPointStateCallback(
        &CmdDrawStructureSlantedColumn::OnEnterGettingEndPointState, this);
    actionInput.ActionDestroyCallback = ActionDrawStraightElementInput::CreateOnActionDestroyCallback(&CmdDrawStructureSlantedColumn::OnActionDestroy, this);
    actionInput.PropertyPanelEventCallback = ActionDrawStraightElementInput::CreateOnPropertyPanelEventCallback(&CmdDrawStructureSlantedColumn::OnPropertyPanelEvent, this);

    OwnerPtr<IAction> opAction = ActionDrawStraightElementCreator::Create(actionInput);

    AddStructureDynamicPannelUtil::SetupColumnCreationContext(opAction.get(), ID_PAGE_GBMP_MODIFY);
    IMainWindow::GetMainWindow()->UpdateControlStatus();

    return TransferOwnership(opAction);
}

Int32 CmdDrawStructureSlantedColumn::GetCategorySecondKey() const
{
    return 0;
}

UniIdentity CmdDrawStructureSlantedColumn::GetCategory() const
{
    return BuiltInCategoryUniIdentities::BICU_STRUCTURE_COLUMN;
}

std::wstring CmdDrawStructureSlantedColumn::GetDefaultFamilyName() const
{
    return STRUCTURE_RECT_COLUMN_NAME;
}

void CmdDrawStructureSlantedColumn::OnActionInit(gcmp::IUiView* pCurrentView)
{
    //当前Modelview
    IModelView* pModelView = UiDocumentViewUtils::GetCurrentModelView();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pModelView, L"invalid pModelView",L"GDMPLab",L"2024-03-30");

    //当前文档
    IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    //创建预设临时对象
    OwnerPtr<IUserTransaction> opTransaction = IUserTransaction::Create(pDoc, GBMP_TR(L"创建预设参数对象"), true);
    ElementId presetColumnId = CreateInstance(Vector3d(0, 0, 0), Vector3d(1, 1, 1), false, false, ElementCreationOptions::Transient);
    opTransaction->Commit();

    //预设参数
    const IInstanceType* pInstanceType = quick_cast<IInstanceType>(pDoc->GetElement(m_instanceTypeId));
    DBG_WARN_AND_RETURN_VOID_UNLESS(pInstanceType, L"pInstanceType获取失败",L"GDMPLab",L"2024-03-30");

    OwnerPtr<IUserTransaction> ut = IUserTransaction::Create(pDoc, GBMP_TR(L"保存当前创建实例的族类型到预设参数"), true);
    bool bOk = StructureInstancePresetParameterUtils::SetPresetInstanceType(pDoc, GetCategory(), GetCategorySecondKey(), pInstanceType->GetElementId());
    DBG_WARN_AND_RETURN_VOID_UNLESS(bOk, L"SetPresetInstanceType失败",L"GDMPLab",L"2024-03-30");
    ut->Commit();

    GbmpPresetParameterUIUtils::UpdatePropertyPanel(presetColumnId);
    GbmpPresetParameterUIUtils::EnablePropertyPanel(true);
}

ElementId CmdDrawStructureSlantedColumn::CreateInstance(const Vector3d& firsrPoint, const Vector3d& secondPoint, bool isVisible, bool canBeShared, ElementCreationOptions createOption /*= gcmp::ElementCreationOptions::Normal*/)
{
    OwnerPtr<StructureColumnInput> opInput = GetInstanceInput();
    {
        opInput->PositionPoints = std::vector<Vector3d>{ firsrPoint,secondPoint };
        opInput->CanBeShared = canBeShared;
        opInput->Visible = isVisible;
        opInput->CreationOption = createOption;
        opInput->IsVerticalColumn = false;
    }

    IStructureSlantedColumn* pColumn = IStructureSlantedColumn::Create(opInput.get());
    DBG_WARN_AND_RETURN_UNLESS(pColumn, ElementId::InvalidID, L"创建柱失败",L"GDMPLab",L"2024-03-30");

    return pColumn->GetElementId();
}

OwnerPtr<StructureColumnInput> CmdDrawStructureSlantedColumn::GetInstanceInput()
{
    OwnerPtr<StructureColumnInput> columnInput = NEW_AS_OWNER_PTR(StructureColumnInput);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(columnInput, L"invalid columnInput",L"GDMPLab",L"2024-03-30");

    IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    IModelView* pModelView = UiDocumentViewUtils::GetCurrentModelView();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    bool bOk = StructureInstanceCmdUtils::GenerateSlantedColumnInput(pDoc, pModelView,
        GetCategory(), GetCategorySecondKey(), m_familyId, m_instanceTypeId, *columnInput);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(bOk, L"GenerateVerticalColumnInput失败",L"GDMPLab",L"2024-03-30");

    return TransferOwnership(columnInput);
}

bool CmdDrawStructureSlantedColumn::SetFamilyIdAndInstanceTypeId(ElementId familyId, ElementId instanceTypeId)
{
    if (m_familyId.HasSameValue(familyId) && m_instanceTypeId.HasSameValue(instanceTypeId))
        return true;

    m_familyId = familyId;
    m_instanceTypeId = instanceTypeId;

    IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    OwnerPtr<IUserTransaction> opTransaction = IUserTransaction::Create(pDoc, GBMP_TR(L"保存当前创建实例的族类型到预设参数"), true);

    bool bOk = StructureInstancePresetParameterUtils::SetPresetInstanceType(pDoc, this->GetCategory(), this->GetCategorySecondKey(), instanceTypeId);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(bOk, L"SetPresetInstanceType失败",L"GDMPLab",L"2024-03-30");

    opTransaction->Commit();
    return true;
}

gcmp::ElementId gcmp::CmdDrawStructureSlantedColumn::OnLineFinished(gcmp::IUiView* pCurrentView, const gcmp::Vector3d& startPt, const gcmp::Vector3d& endPt, const gcmp::ISnap* pStartSnap, const gcmp::ISnap* pEndSnap)
{
    IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
    DBG_WARN_AND_RETURN_UNLESS(pDoc,ElementId::InvalidID, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    OwnerPtr<IUserTransaction> ut = IUserTransaction::Create(pDoc, GBMP_TR(L"创建GBMP普通线式族实例"));
    ElementId ColumnId = CreateInstance(startPt, endPt, true, false);
    ut->Commit();

    return ColumnId;
}

gcmp::OwnerPtr<gcmp::IGraphicsNodeGroup> gcmp::CmdDrawStructureSlantedColumn::OnLineUpdate(gcmp::IUiView* pCurrentView, const gcmp::Vector3d& startPt, const gcmp::Vector3d& endPt)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(nullptr != pCurrentView, L"pCurrentView为空",L"GDMPLab",L"2024-03-30");

    if (Vector3dUtils::IsEqual(startPt, endPt, gcmp::Constants::MIN_MODEL_SIZE))
        return nullptr;

    IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    OwnerPtr<IUserTransaction> ut = IUserTransaction::Create(pDoc, GBMP_TR(L"创建预览对象"));

    ElementId columnId = CreateInstance(startPt, endPt, true, false);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(columnId.IsValid(), L"columnId为空",L"GDMPLab",L"2024-03-30");

    IInstance *pColumn = quick_cast<IInstance>(pDoc->GetElement(columnId));
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pColumn, L"pColumn为空",L"GDMPLab",L"2024-03-30");

    //3. 获得辅助非临时Instance的Grep
    OwnerPtr<IGraphicsElementShape> tempGrep = TransferOwnershipCast<IGraphicsElementShape>(pColumn->GetElementModelShape()->GetGraphicsElementShape()->Clone());
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(tempGrep != nullptr, L"tempGrep指针无效",L"GDMPLab",L"2024-03-30");
    OwnerPtr<IGraphicsNodeGroup> tempGpGrep = gcmp::GbmpGraphicsNodeUtils::TransferGRepToGGroup(TransferOwnership(tempGrep));
    tempGpGrep->SetIsSnappable(false);

    ut->Rollback();

    //4. 两点之间连线
    tempGpGrep->AddChild(TransferOwnership(IGraphicsLine::Create(startPt, endPt)));

    //// 临时尺寸标注
    //Vector3d angleStartPt = startPt + Vector3d::UnitX * 1000;
    //OwnerPtr<ITemporaryDimensionContext> opCtx = ITemporaryDimensionContext::CreateRotationContext(
    //    startPt, angleStartPt, endPt, GbmpModelViewUtil::GetWorkPlaneCoordinate(pCurrentView->GetModelView()));
    //tempGpGrep->AddChild((ITemporaryDimensionManager::Get()->GenerateTemporaryDimensionGraphics(opCtx.get())));

    // 如果 IGraphicsElementShape 在事务中创建且事务被撤消了，那么 IGraphicsElementShape 上的样式或      者材质的 ElementId 可能就引用到了一个被销毁的 Element 对象上（族文档中有样式或材质被映射到主文档）
    // 下面的代码是将 IGraphicsElementShape 上的样式和材质的 ElementId 全部清空，并将 IGraphicsElementShape 以“临时对象样式”进行渲染
    GraphicsNodeUtils::CleanGraphicsNodeStyleAndMaterial(pDoc, tempGpGrep.get());
    tempGpGrep->SetGraphicsStyleId(pDoc->GetGraphicsStyleManager()->GetGraphicsStyleIdByCategoryUid(BuiltInCategoryUniIdentities::BICU_TEMP_STYLE));

    return TransferOwnership(tempGpGrep);
}

void CmdDrawStructureSlantedColumn::OnActionDestroy()
{
    GbmpPresetParameterUIUtils::UpdatePropertyPanel(ElementId::InvalidID);
    GbmpPresetParameterUIUtils::EnablePropertyPanel(true);
}

void CmdDrawStructureSlantedColumn::OnEnterGettingEndPointState(gcmp::IUiView* pCurrentView)
{
    GbmpPresetParameterUIUtils::EnablePropertyPanel(false);
}

void CmdDrawStructureSlantedColumn::OnEnterGettingStartPointState(gcmp::IUiView* pCurrentView)
{
    GbmpPresetParameterUIUtils::EnablePropertyPanel(true);
}

void CmdDrawStructureSlantedColumn::OnPropertyPanelEvent(gcmp::IPropertyPanelEventArgs* pArgs)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pArgs, L"pArgs为空",L"GDMPLab",L"2024-03-30");

    IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    // TODO: 接口
    if (PropertyWidgetUtils::IsComponentTypeChangedEvent(pArgs->GetPropertyItemUniqueId()))
    {
        ElementId newInstanceTypeId(StringUtil::ToNumber<Int64>(pArgs->GetNewValue()));
        DBG_WARN_AND_RETURN_VOID_UNLESS(newInstanceTypeId.IsValid(), L"newInstanceTypeId无效",L"GDMPLab",L"2024-03-30");

        ElementId newFamilyId;
        bool bOk = StructureFamilyUtils::GetFamilyIdByTypeId(pDoc, newInstanceTypeId, newFamilyId);
        DBG_WARN_AND_RETURN_VOID_UNLESS(bOk, L"GetFamilyNameByTypeId失败",L"GDMPLab",L"2024-03-30");

        if (m_familyId.HasSameValue(newFamilyId) && m_instanceTypeId.HasSameValue(newInstanceTypeId))
            return;

        //缓存，并设置预设参数
        SetFamilyIdAndInstanceTypeId(newFamilyId, newInstanceTypeId);
    }
}

REGISTER_GM_COMMAND(CmdDrawStructureSlantedColumn)
